using System.Collections.Generic;
using System.Text;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace WorkFlow.Tools.UI
{
    [ExecuteAlways]
    public class UIBehaviourDriver : UIBehaviour
    {
        private IUIBehaviourDriverElement[] _elements;
        [ReadOnly][ShowInInspector][TextArea(1,10)]
        private string elementsStr;
        RectTransform rectTransform => transform as RectTransform;
        protected override void Start()
        {
            base.Start();
            FindReferences();
            UpdateElement();
        }
        protected override void OnEnable()
        {
            base.OnEnable();
            FindReferences();
            UpdateElement();
        }
        
        public void ForceRefresh()
        {
            UpdateElement();
        }
        
        void FindReferences()
        {
            _elements = gameObject.GetComponents<IUIBehaviourDriverElement>();
            if(_elements!=null && _elements.Length > 0)
            {
                System.Array.Sort(_elements, (a, b) => a.Order - b.Order);
            }
#if UNITY_EDITOR
            StringBuilder sb = new StringBuilder();
            foreach (var item in _elements)
            {
                sb.AppendLine(item.ToString());
            }
            elementsStr = sb.ToString();
#endif
        }

        private bool _executing = false;
        
        protected override void OnRectTransformDimensionsChange()
        {
            UpdateElement();
        }

        void UpdateElement()
        {
            if (_executing) return;
            if(_elements == null || _elements.Length == 0)
            {
                return;
            }
            _executing = true;
            foreach (var item in _elements)
            {
                if (item.ElementEnabled)
                {
                    item.OnRectTransformDimensionsChange();
                }
            }
            _executing = false;
        }

        
        #if UNITY_EDITOR
        void Update()
        {
            if (!Application.isPlaying)
            {
                if (_executing) return;
                if (_elements == null || _elements.Length == 0)
                {
                    return;
                }

                _executing = true;
                bool hasChange = false;
                foreach (var item in _elements)
                {
                    if (item.ElementEnabled && item.IsValidated)
                    {
                        hasChange = true;
                        item.OnRectTransformDimensionsChange();
                    }
                }

                if (hasChange)
                    LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
                _executing = false;
            }
        }
        #endif
    }
    
    public interface IUIBehaviourDriverElement
    {
        int Order { get; }
        bool ElementEnabled { get; }
#if UNITY_EDITOR
        bool IsValidated { get; }
#endif
        void OnRectTransformDimensionsChange();
    }
}

